package com.zc.custom;

import com.zc.enums.StatusEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @description:
 * @author: cong
 * @create: 2024/12/31
 */
public class CustomTypeHandler extends BaseTypeHandler<StatusEnum> {
    /**
     * 设置非空参数到PreparedStatement中
     * 此方法专门用于处理StatusEnum类型的参数，将其代码值设置到指定的位置
     *
     * @param ps PreparedStatement对象，用于执行SQL语句
     * @param i 参数的索引位置，从1开始计数
     * @param parameter StatusEnum类型的参数，代表某种状态
     * @param jdbcType 参数的JDBC类型，对于此方法而言并非必需，因为StatusEnum类型已确定
     * @throws SQLException 如果设置参数过程中出现错误，将抛出此异常
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, StatusEnum parameter, JdbcType jdbcType) throws SQLException {
        // 将StatusEnum的代码值设置到PreparedStatement的指定位置
        ps.setInt(i, parameter.getCode());
    }

    /**
     * 从ResultSet中获取指定列名的值，并将其转换为StatusEnum类型
     * 如果数据库中的值为NULL，则返回null
     *
     * @param rs ResultSet对象，包含查询结果
     * @param columnName 列名，用于指定需要获取数据的列
     * @return StatusEnum类型的枚举值，或者null（如果数据库中的值为NULL）
     * @throws SQLException 如果在处理ResultSet时发生SQL异常
     */
    @Override
    public StatusEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 从ResultSet中获取指定列名的整数值
        int code = rs.getInt(columnName);
        // 检查获取的值是否为NULL
        if (rs.wasNull()) {
            // 如果值为NULL，返回null
            return null;
        }
        // 如果值不为NULL，根据获取的整数值返回对应的StatusEnum枚举值
        return StatusEnum.getByCode(code);
    }

    @Override
    public StatusEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex);
        // 检查获取的值是否为NULL
        if (rs.wasNull()) {
            // 如果值为NULL，返回null
            return null;
        }
        // 如果值不为NULL，根据获取的整数值返回对应的StatusEnum枚举值
        return StatusEnum.getByCode(code);
    }

    /**
     * 从CallableStatement中获取可空结果并转换为StatusEnum枚举类型
     * 此方法主要用于数据库操作中，当执行一个存储过程调用时，
     * 通过列索引从结果集中获取一个可能为NULL的值，并将其转换为相应的StatusEnum枚举实例
     *
     * @param cs CallableStatement实例，用于执行存储过程并获取结果
     * @param columnIndex 结果集中的列索引，用于指定需要获取值的列
     * @return StatusEnum枚举实例，如果结果集中指定列的值为NULL，则返回null
     * @throws SQLException 如果在执行数据库操作过程中发生错误
     */
    @Override
    public StatusEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 从CallableStatement中按列索引获取int类型的值
        int code = cs.getInt(columnIndex);
        // 检查上一个从ResultSet获取的值是否为SQL NULL值
        if (cs.wasNull()) {
            // 如果是NULL值，则返回null
            return null;
        }
        // 根据获取到的代码返回对应的StatusEnum枚举实例
        return StatusEnum.getByCode(code);
    }
}
